package com.fanben100.biz;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Toolkit;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;

import com.fanben100.constant.SystemConstant;
import com.fanben100.domain.LoginModel;
import com.fanben100.domain.Seller;
import com.fanben100.domain.SysConfig;
import com.fanben100.util.CryptoTools;
import com.fanben100.util.SerializeUtil;

/**
 * 
 * @author CYC
 * 
 */
public final class RegistContext implements PropertyChangeListener {

	private SystemState sysState;

	private int repeatCount = 0;

	private final JProgressBar jpb = new JProgressBar(0, 50);

	private void initContext(JFrame frame) {
		sysState.handle(frame);
	}

	private Object dest = null;

	ValidLoginModel currentModel = null;

	private LoginTemplate loginTemplate = new SellerLogin();

	private TimerTask connectTask = null;

	private JFrame jf;

	public void checkRegist(JFrame frame) {
		// SystemState currentState = RegistContext.getInstance().sysState;
		unvalidRegist(frame);
		validWating(frame);
		// 没有检查过的就就行检查，否则忽略
		// if (currentState == null) {
		dest = SerializeUtil.deserialize(SystemConstant.KEY_STORE_NAME);
		if (dest != null && dest instanceof Seller) {
			Seller seller = (Seller) dest;
			String encodePass = seller.getLoginPassword();
			String encodeIdentity = seller.getIdentify();
			String sourcePass = null;
			String sourceIdentity = null;
			try {
				sourcePass = CryptoTools.getInstance().decode(encodePass);
			} catch (Exception e) {
				e.printStackTrace();
			}
			try {
				sourceIdentity = CryptoTools.getInstance().decode(
						encodeIdentity);
			} catch (Exception e) {
				e.printStackTrace();
			}
			seller.setLoginPassword(sourcePass);
			seller.setIdentify(sourceIdentity);
			ValidLoginModel checkResult = loginTemplate
					.directLogin((Seller) dest);
			if (checkResult.isNetFault()) {
				// 网络验证失败，检查连网状态
				Object[] options = { "是", "否" };
				int response = JOptionPane
						.showOptionDialog(frame, "网络验证商家注册信息失败，请检查联网状态",
								"是否重连", JOptionPane.YES_OPTION,
								JOptionPane.QUESTION_MESSAGE, null, options,
								options[0]);
				if (response == 0) {
					repeatConnect();
					// System.out.println("您按下了第OK按钮 ");
				} else if (response == 1) {
					System.exit(0);
					// System.out.println("您按下了第Cancel按钮 ");
				}
				SysConfig.sellerLoginModel = currentModel;
				// JOptionPane.showOptionDialog(frame,
				// "网络验证商家注册信息失败，请检查联网状态","是否重连",JOptionPane.YES_NO_OPTION);
			} else {
				if (checkResult.isValid()) {
					sysState = new RegistState();
					SysConfig.sellerLoginModel = checkResult;
				} else {
					sysState = new UnRegistState();
				}
			}
		} else {
			sysState = new UnRegistState();
		}
		// }
		initContext(frame);
	}

	public SystemState getSysState() {
		return sysState;
	}

	/**
	 * 此方法慎用
	 * 
	 * @param sysState
	 */
	public void setSysState(SystemState sysState, JFrame frame) {
		if (sysState != this.sysState) {
			// 如果与当前状态不同，则重新处理
			this.sysState = sysState;
			this.sysState.handle(frame);
		}
	}

	private static class SingletonHolder {
		private static RegistContext instance = new RegistContext();
	}

	private RegistContext() {
	}

	public static RegistContext getInstance() {
		return SingletonHolder.instance;
	}

	/**
	 * 商家注册软件
	 * 
	 * @return
	 */
	public ValidLoginModel regist(LoginModel seller) {
		LoginTemplate loginTemplate = new SellerLogin();
		ValidLoginModel checkResult = loginTemplate.directLogin(seller);
		String sourceIdentity =null;
		if (checkResult.isValid()) {
			CryptoTools cryptTool = CryptoTools.getInstance();
			String encodePass = null;
			String encodeIdentity = null;
			sourceIdentity = checkResult.getIdentify();
			try {
				encodePass = cryptTool.encode(checkResult.getLoginPassword());
			} catch (Exception e) {
				e.printStackTrace();
			}
			try {
				encodeIdentity = cryptTool.encode(checkResult.getIdentify());
			} catch (Exception e) {
			}
			checkResult.setIdentify(encodeIdentity);
			checkResult.setLoginPassword(encodePass);
			SerializeUtil.serialize(SystemConstant.KEY_STORE_NAME, seller);
		}
		checkResult.setIdentify(sourceIdentity);
		return checkResult;
	}

	private class ConnectTimerTask extends TimerTask {
		@Override
		public void run() {
			currentModel = loginTemplate.directLogin((Seller) dest);
			System.out.println("try connection,relogin");
			repeatCount++;
		}
	}

	public void repeatConnect() {
		Timer timer = new Timer();
		connectTask = RegistContext.getInstance().new ConnectTimerTask();
		timer.schedule(connectTask, 1000, 5000);// 在1秒后执行此任务,每次间隔5秒,如果传递一个Data参数,就可以在某个固定的时间执行这个任务.
		while (true) {// 这个是用来停止此任务的,否则就一直循环执行此任务了
			if (currentModel != null && !currentModel.isNetFault()) {
				timer.cancel();// 使用这个方法退出任务
				connectTask = null;
				if (currentModel.isValid()) {
					this.sysState = new RegistState();
				} else {
					this.sysState = new UnRegistState();
				}
				break;
			} else {
				// 自动重试5次
				if (repeatCount == 5) {
					repeatCount = 0;
					timer.cancel();
					connectTask = null;
					JOptionPane.showMessageDialog(null, "连接网络失败");
					System.exit(0);
				}
			}
			try {
				Thread.sleep(1000 * 5);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("repeat valid net connect");
		}
	}

	class Task extends SwingWorker<Void, Void> {
		/*
		 * Main task. Executed in background thread.
		 */
		@Override
		public Void doInBackground() {
			Random random = new Random();
			int progress = 0;
			// Initialize progress property.
			setProgress(0);
			// Sleep for at least one second to simulate "startup".
			try {
				Thread.sleep(1000 + random.nextInt(2000));
			} catch (InterruptedException ignore) {
			}
			while (RegistContext.getInstance().sysState == null) {
				// Sleep for up to one second.
				try {
					Thread.sleep(random.nextInt(1000));
				} catch (InterruptedException ignore) {
				}
				// Make random progress.
				progress += random.nextInt(10);
				setProgress(Math.min(progress, 100));
			}
			jf.dispose();
			return null;
		}

		/*
		 * Executed in event dispatch thread
		 */
		public void done() {
			Toolkit.getDefaultToolkit().beep();
		}
	}

	/**
	 * 
	 */
	private void validWating(JFrame frame) {
		JLabel noticeLabel = new JLabel("正在验证商户注册信息...", JLabel.CENTER);
		jf = new JFrame();
		Image icon = Toolkit.getDefaultToolkit().createImage(
				this.getClass().getResource("/img/logo.gif"));
		jf.setIconImage(icon);
		jf.setUndecorated(true);
		jf.setLocationRelativeTo(frame);
		jf.setSize(new Dimension(200, 20));
		JPanel jp = new JPanel();
		jp.setLayout(new BorderLayout());
		jp.add(noticeLabel, BorderLayout.PAGE_START);
		jp.add(jpb, BorderLayout.CENTER);
		jf.add(jp);
		jf.pack();
		jpb.setStringPainted(true);
		jpb.setIndeterminate(true);
		jpb.setBackground(Color.orange);
		jpb.setForeground(Color.blue);
		// jf.setLocation(200, 300);
		jf.setVisible(true);
		// jf.setDefaultCloseOperation(JDialog.EXIT_ON_CLOSE);
		Task task = new Task();
		task.addPropertyChangeListener(this);
		task.execute();
	}

	public void propertyChange(PropertyChangeEvent evt) {
		if ("progress" == evt.getPropertyName()) {
			int progress = (Integer) evt.getNewValue();
			jpb.setIndeterminate(false);
			jpb.setValue(progress);
		}
	}

	private void unvalidRegist(JFrame frame) {
		int menuCount = frame.getJMenuBar().getMenuCount();
		for (int i = 0; i < menuCount; i++) {
			JMenu menu = frame.getJMenuBar().getMenu(i);
			// menu.setEnabled(false);
			int menuItemCount = menu.getItemCount();
			for (int j = 0; j < menuItemCount; j++) {
				JMenuItem item = menu.getItem(j);
				// 除了注册菜单，其余菜单禁用
				if (item == null) {
					continue;
				}
				if (!SystemConstant.REGIST_MENU_TEXT.equals(item.getText())) {
					item.setEnabled(false);
				}
			}
		}
	}
}
